/**
 *  
 *
 */
package com.mxl.common;

import java.beans.PropertyDescriptor;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.util.Assert;

import com.mxl.service.channel.CommCallbackRequest;

/**
 * Bean属性转换工具类.
 * 
 * @author mxl
 */
public class BeanConvertUtil {
	private static final Logger logger = LoggerFactory
			.getLogger(BeanConvertUtil.class);

	/**
	 * 把Bean数据转换为另外一个类的对象中.
	 * 
	 * @param targetClass
	 *            目标对象的类,必须有public 的 无参数的 construct method.
	 * @param sourceObject
	 *            数据源
	 * @return 数据目标
	 */
	public static Object convert(Class targetClass, Object sourceObject,
			String[] ignoreProperties) {
		Assert.notNull(sourceObject, sourceObject + "  is null");
		try {
			Object targetObject = targetClass.newInstance();
			if (ignoreProperties == null) {
				BeanUtils.copyProperties(sourceObject, targetObject);
			} else {
				BeanUtils.copyProperties(sourceObject, targetObject,
						ignoreProperties);
			}
			return targetObject;
		} catch (InstantiationException e) {
			logger.error("Can't create Instance of Class:" + targetClass, e);
		} catch (IllegalAccessException e) {
			logger.error("Can't access construct method of Class:"
					+ targetClass, e);
		}
		return null;
	}

	/**
	 * 把Bean数据转换为另外一个类的对象集合中.
	 * 
	 * @param targetClass
	 *            目标对象的类,必须有public 的 无参数的 construct method.
	 * @param sources
	 *            数据源
	 * @return 数据目标
	 */
	public static Collection convert(Class targetClass, Collection sources) {
		if (sources == null || sources.isEmpty()) {
			return null;
		}
		try {
			Collection targets = sources.getClass().newInstance();
			for (Object sourceObject : sources) {
				Object targetObject = targetClass.newInstance();
				BeanUtils.copyProperties(sourceObject, targetObject);
				targets.add(targetObject);
			}
			return targets;
		} catch (InstantiationException e) {
			logger.error("Can't create Instance of Class:" + targetClass, e);
		} catch (IllegalAccessException e) {
			logger.error("Can't access construct method of Class:"
					+ targetClass, e);
		}
		return null;
	}

	public static String getPropertyValueAsText(final Object bean,
			final String propName) {
		BeanWrapper wrapper = new BeanWrapperImpl(bean);

		return String.valueOf(wrapper.getPropertyValue(propName));
	}

	/**
	 * Get property value from the given bean of the given name as Integer.
	 * 
	 * @param bean
	 * @param propName
	 * @return
	 */
	public static Integer getPropertyValueAsLong(final Object bean,
			final String propName) {
		BeanWrapper wrapper = new BeanWrapperImpl(bean);

		return (Integer) wrapper.getPropertyValue(propName);
	}

	/**
	 * 将指定对象转换为Map<String,String>对象.
	 * 
	 * @param obj
	 * @return
	 */
	public static Map<String, String> bean2Map(Object obj) {
		if (null == obj) {
			return null;
		}
		Map<String, String> map = new HashMap<String, String>();
		BeanWrapper wrapper = new BeanWrapperImpl(obj);
		PropertyDescriptor[] propertys = wrapper.getPropertyDescriptors();

		for (int i = 0; i < propertys.length; i++) {
			String propertyName = propertys[i].getName();
			Object value = wrapper.getPropertyValue(propertyName);
			// if (!isNull(value) && !value.equals(obj.getClass())) {
			map.put(propertyName, value == null ? "" : value.toString());
			// }
		}
		map.remove("class");
		return map;
	}

	private static boolean isNull(Object object) {
		if (object instanceof String) {
			return isEmpty(object.toString());
		}
		return object == null;
	}

	private static boolean isEmpty(final String value) {
		return value == null || value.trim().length() == 0;
	}

	public static void main(String[] args) {
		CommCallbackRequest callbackRequest = new CommCallbackRequest();
		System.err.println(bean2Map(callbackRequest));
		callbackRequest.setErrcode("1111111");
		System.err.println(bean2Map(callbackRequest));
	}
}
